#ifndef BULLET_H
#define BULLET_H

#include "utils.h"
#include <QPointF>
#include <QRect>
#include <QVector>

class Bullet{
public:
    Bullet(int camp, float radius = 25, float v = 800, float frequency = 13)
        :_camp(camp), _radius(radius), _v(v), _frequency(frequency)
    {}

    // 直线, 球的中心从 (src_x, src_y) 到 (dst_x, dst_y)
    void setStyle_line(float src_x, float src_y, float dst_x, float dst_y)
    {
        float X = dst_x - src_x;
        float Y = dst_y - src_y;
        float S = std::pow(X*X + Y*Y, 0.5);
        float V = _v / 1000 * _frequency;
        int count_of_step = S / V;

        _path.resize(count_of_step + 1);
        float dx = X / count_of_step;
        float dy = Y / count_of_step;

        // 设置路径
        for(int i = 0; i <= count_of_step; i++)
            _path[i] = QPoint(src_x + i*dx, src_y + i*dy);
    }

    QPointF setStyle_bezier(float src_x, float src_y, float dst_x, float dst_y) // : _src_x(src_x), _src_y(src_y), _dst_x(dst_x), _dst_y(dst_y)
    {
        float X = dst_x - src_x;
        float Y = dst_y - src_y;
        float S = sqrt(X*X + Y*Y);
        float V = _v / 1000 * _frequency;
        int count_of_step = S / V;

        _path.resize(count_of_step + 1);

        src_x -= _radius;
        src_y -= _radius;
        dst_x -= _radius;
        dst_y -= _radius;

        QPointF a(src_x, src_y), c(dst_x, dst_y);
        QPointF ac = c - a; // a->c的向量
        float length = sqrt(ac.x() * ac.x() + ac.y() * ac.y());

        if (length < 0.000001) ac = {1, 0};
        else ac = {ac.x() / length, ac.y() / length};

        QPointF ac_(ac.y(), -ac.x()); // 垂直
        float r = rand() % 80 / 80.0 - 0.4;
        QPointF b = (a + ac * 0.1 * r * (0.5)) + ac_ * r * length;

        // 设置路径
        for(int i = 0; i <= count_of_step; i++){
            float t = (float)i / count_of_step;
            _path[i] = Utils::getLerp(a, b, c, t).toPoint();
        }
        return b;
    }

    void arrive(){_arrived = true;}

    bool update(){
        if(_arrived) return false;
        _cur_step++;
        if(_cur_step >= _path.size()) _arrived = true;
        return true;
    }

    bool timeout() const {return _arrived || _cur_step >= _path.size();}

    QRect getRect() const {
        return QRect(_path[std::min(_cur_step, _path.size() - 1)], QSize(_radius, _radius));
    }

    QPointF getDirectionV() const {
        QPointF ac = _path.front() - _path.back(); // a->c的向量
        float length = sqrt(ac.x() * ac.x() + ac.y() * ac.y());
        if (length < 0.000001)
            return QPointF(ac.y(), -ac.x()); // 垂直
        return {ac.y() / length, -ac.x() / length};
    }

    QPointF getDirection() const {
        QPointF ac = _path.front() - _path.back(); // a->c的向量
        float length = sqrt(ac.x() * ac.x() + ac.y() * ac.y());
        if (length < 0.000001)
            return QPointF(ac.x(), ac.y());
        return {ac.x() / length, ac.y() / length};
    }

    const int& camp() const {return _camp;}

    const QPointF pos() const {
        return _path[std::min(_cur_step, _path.size() - 1)];
    }

    const float& radius () const {return _radius;}
private:
    bool _arrived = false;
    int _cur_step = 0;

    const int _camp;
    float _radius;
    float _v;
    float _frequency;
    QVector<QPoint> _path;
};


struct Particle {
    Particle(QPointF pos, int steps = 30)
        : curpos(pos), lifetime(steps), maxLifetime(steps) {}

    // dir = 目标方向的单位向量
    void line(const QPointF& dir){
        direction = dir;
    }

    // 总之每步1像素
    void circle(float angle){
        float d = 1;
        float dx = d * std::cos(angle);
        float dy = d * std::sin(angle);
        direction = QPointF(dx, dy);
    }

    void update(int dec = 1) {
        curpos += direction;
        lifetime -= dec;
    }

    bool isAlive() const {
        return lifetime > 0;
    }

    QPointF curpos;
    QPointF direction;
    int lifetime;
    int maxLifetime;
};

#endif // BULLET_H
